//=======================================================================
//文件名称：gpio.c
//功能概要：GPIO底层驱动构件源文件
//芯片类型：STC89C52
//版权所有：HCIT-SMh
//版本更新：2020-02-20  V1.0
//======================================================================
//1.包含本构件头文件
#include "gpio.h" 

//2.对仅用于本文件的全局变量和内部函数的声明
//(1)定义全局变量

//(2)内部函数声明
static void gpio_port_pin(uint_8 port_pin, uint_8 *port, uint_8 *pin);

//3.对外接口函数的定义与实现
//=======================================================================
//函数名称：gpio_pin_set
//函数功能：设置指定引脚的输出状态
//函数参数：port_pin：(端口号)|(引脚号)（例：PORT_1|5 表示P1.5引脚）
//          state：希望设置的端口引脚状态（0为低电平，1为高电平）
//函数返回：无
//=======================================================================
void gpio_pin_set(uint_8 port_pin, bit state)
{
    uint_8 port, pin;
    gpio_port_pin(port_pin, &port, &pin);
    switch(port)
    {
        case 0:
            if(state==0) BCLR(P0, pin);
            else         BSET(P0, pin);
            break;      
        case 1:
            if(state==0) BCLR(P1, pin);
            else         BSET(P1, pin);
            break;    
        case 2:
            if(state==0) BCLR(P2, pin);
            else         BSET(P2, pin);
            break;   
        case 3:
            if(state==0) BCLR(P3, pin);
            else         BSET(P3, pin);
            break;    			
    }
}

//=======================================================================
//函数名称：gpio_pin_get
//函数功能：获取指定引脚的输入状态
//函数参数：port_pin：(端口号)|(引脚号)（例：PORT_1|5 表示P1.5引脚）
//函数返回：指定端口引脚的状态（1或0）
//=======================================================================
bit gpio_pin_get(uint_8 port_pin)
{
    uint_8 port, pin;
    bit state;
    gpio_port_pin(port_pin, &port, &pin);
    switch(port)
    {
        case 0:
           BSET(P0, pin); _nop_();
           state = BGET(P0, pin);
           break;      
        case 1:
           BSET(P1, pin); _nop_();
           state = BGET(P1, pin);
           break;     
        case 2:
           BSET(P2, pin); _nop_();
           state = BGET(P2, pin);
           break;   
        case 3:
           BSET(P3, pin); _nop_();
           state = BGET(P3, pin);
           break;     			
    }
    return  (state);    
}

//=======================================================================
//函数名称：gpio_pin_reverse
//函数功能：反转指定引脚的状态
//函数参数：port_pin：(端口号)|(引脚号)（例：PORT_1|5 表示P1.5引脚）
//函数返回：无
//=======================================================================
void gpio_pin_reverse(uint_8 port_pin)
{
    uint_8 port, pin;
    gpio_port_pin(port_pin, &port, &pin);
    switch(port)
    {
        case 0:
            BRVS(P0, pin); break;      
        case 1:
            BRVS(P1, pin); break;     
        case 2:
            BRVS(P2, pin); break;   
        case 3:
            BRVS(P3, pin); break;;     			
    }  
}

//=======================================================================
//函数名称：gpio_port_set
//函数功能：设置指定端口的输出状态
//函数参数：port：端口号（例：PORT_1表示P1端口）
//          state：希望设置的端口状态
//函数返回：无
//=======================================================================
void gpio_port_set(uint_8 port, uint_8 state)
{
    switch(port>>4)
    {
        case 0:
            P0 = state; break;      
        case 1:
            P1 = state; break;    
        case 2:
            P2 = state; break;
        case 3:
            P3 = state; break;    			
    }
}

//=======================================================================
//函数名称：gpio_port_get
//函数功能：获取指定端口的输入状态
//函数参数：port：端口号（例：PORT_1表示P1端口）
//函数返回：指定端口的状态
//=======================================================================
uint_8 gpio_port_get(uint_8 port)
{
    uint_8 state;
    switch(port>>4)
    {
        case 0:
            P0 = 0xff;  _nop_();
            state = P0;
            break;      
        case 1:
            P1 = 0xff;  _nop_();
            state = P1;
            break;     
        case 2:
            P2 = 0xff;  _nop_();
            state = P2;
            break;   
        case 3:
            P3 = 0xff;  _nop_();
            state = P3;
            break;     			
    }
    return  (state);    
}

//4.内部函数的定义与实现
//===========================================================================
//函数名称：gpio_port_pin
//函数功能：对传入参数port_pin进行解析，得出并传回引脚对应的端口号与端口引脚号
//         例如，PORT_1|(5)对应的端口号*port=1（P1端口），端口引脚号*pin=5
//函数参数：port_pin：端口号|引脚号（例：PORT_1|5 表示P1.5引脚）
//          port：用于传回端口号（0～3对应P0～P3）
//	        pin: 用于传回端口引脚号(0～7)
//===========================================================================
static void gpio_port_pin(uint_8 port_pin, uint_8 *port, uint_8 *pin)
{
    *port = port_pin>>4;       //获取端口号
    *pin = port_pin & 0x0f;    //获取端口引脚号
}
